import moment from 'moment';
import cluster from 'cluster';
import {
    getWxAccessToken,
    getWechatIdBySn,
} from '../controllers/wx_token';
import {
    sendToWXUser,
} from './wx_handle';

import { exesql, insertTable } from '../database/db';
import { sendLogToEmail } from '../controllers/logger';
import { sendNewVoice } from '../database/redis_db';
import { control, audioCustomPlay} from '../controllers/baidu_api';
import { sendMessageToDevice } from './mqtt_handler';
import { API_CODE_SERVER_ERR, API_CODE_NOT_STORE_AUDIO, NOT_SUPPORT_COLLECT_AUDIO } from '../config/api_code';
import { WX_MESSAGE_VALID_TIME, PLAY_LIST_LIMIT_SIZE ,NOTIFY_MASTER_RELOAD_PLARFORM,FAVORITE_CATEGORY_ID } from '../config/config';
import { checkNumber } from '../controllers/utils';


/**
 * 不对其进行拦截的API
 */
class ThirdApi {
    constructor() {
        // 设备相关
        this.newWxMessage = this.newWxMessage.bind(this);
        this.getWxAudio = this.getWxAudio.bind(this);
        this.deviceOnlineNotification = this.deviceOnlineNotification.bind(this);
        this.audioChanged = this.audioChanged.bind(this);
        this.deviceInfoChanged = this.deviceInfoChanged.bind(this);
        this.getWxAccessTokenToDevice = this.getWxAccessTokenToDevice.bind(this);

        // 百度相关
        this.saveBaiduVoiceInfo = this.saveBaiduVoiceInfo.bind(this);
        this.verifyBaiduToken = this.verifyBaiduToken.bind(this);
        this.customPlayList = this.customPlayList.bind(this);
        this.playCategory = this.playCategory.bind(this);

        // 重新加载公众号信息
        this.reloadPublicPlatform = this.reloadPublicPlatform.bind(this);
        this.deviceCollectAudio = this.deviceCollectAudio.bind(this);
    }


    // 设备端上传的新消息
    async newWxMessage(req, res) {
        const device_id = req.query.device_id;
        const media_id = req.query.media_id;
        console.log(`device_id:${device_id},  media_id:${media_id}`);
        res.apiSuccess();
        try {
            if (!media_id) {
                console.log(`设备端:${device_id}上传消息的media_id为空`);
                return;
            }

            const wechatId = getWechatIdBySn(device_id);
            const accessToken = await this.getWxToken(wechatId);
            if (accessToken === '') {
                sendLogToEmail(`newWxMessage wechatId:${wechatId}, 获取不到token,${device_id}`);
                return;
            }
            const sql = 'SELECT `open_id` FROM `device_openid` WHERE `device_sn` = ? ;';
            const { err, result } = await exesql(sql, [device_id]);
            if (err) {
                sendLogToEmail(err);
                return;
            }
            for (let index = 0; index < result.length; index++) {
                const item = result[index];
                sendNewVoice(accessToken, device_id,item.open_id,media_id,0);
                // const mResult = await sendToWXUser(accessToken, item.open_id, media_id);
                // if (mResult.result && mResult.result.errcode === 45047) {
                //     // 存储设备发送的消息作为离线消息,用户拉取最新消息后发送离线消息
                //     await insertTable({ device_sn: device_id, media_id: media_id, open_id: item.open_id, status: 0 }, 'wx_offline_voice');
                // }
                // await this.sleep(500);
            }
        } catch (err) {
            sendLogToEmail(err);
        }
    }

    // 设备获取微信音频URL
    async getWxAudio(req, res) {
        const device_id = req.query.device_id;
        let ret = {
            errcode: 0,
            errmsg: 'ok',
            url: ''
        };

        const date = new Date((new Date().getTime() - WX_MESSAGE_VALID_TIME));
        const beforeThirdDay = moment(date).format('YYYY-MM-DD HH:mm:ss.SSS');
        const findSql = 'SELECT `media_id` FROM `wx_voice` WHERE `device_sn` = ? and `status` = 0 AND `last_access` > ? order by `void_id` asc LIMIT 1;';
        try {
            const { err, result } = await exesql(findSql, [device_id, beforeThirdDay]);
            if (err) {
                sendLogToEmail(err);
                res.end(JSON.stringify(ret));
                return;
            }
            if (result.length === 0) {
                res.end(JSON.stringify(ret));
                return;
            }
            const wechatId = getWechatIdBySn(device_id);
            const accessToken = await this.getWxToken(wechatId);
            if (accessToken === '') {
                sendLogToEmail(`getWxAudio wechatId:${wechatId}, 获取不到token,${device_id}`);
                res.end(JSON.stringify(ret));
                return;
            }
            // 更新URL，并且返回
            Object.assign(ret, { url: 'http://api.weixin.qq.com/cgi-bin/media/get?access_token=' + accessToken + '&media_id=' + result[0].media_id });
            const updateSql = 'update wx_voice set status=1 where media_id=?';
            const updateResult = await exesql(updateSql, [result[0].media_id]);
            if (updateResult.err) {
                sendLogToEmail(updateResult.err);
            }
            res.end(JSON.stringify(ret));

        } catch (err) {
            sendLogToEmail(err);
            res.end(JSON.stringify(ret))
        }
    }

    // 设备上传播放音频信息
    async audioChanged(req, res) {
        const uuid = req.query.uuid;
        const device_id = req.query.device_id;
        const audioItemId = req.query.audioItemId;
        const status = req.query.status;

        if (!checkNumber(audioItemId)) {
            return;
        }
        const sql = 'insert into audio_play_log(sn, uuid, audioItemId)values(?,?,?)';
        try {
            const { err } = await exesql(sql, [device_id, uuid, Number(audioItemId)]);
            if (err) {
                sendLogToEmail(err);
            }
        } catch (err) {
            sendLogToEmail(err);
        } finally {
            res.apiSuccess();
            if (!status || status == 'finish') {
                // 发送MQTT消息
                sendMessageToDevice(1, device_id, { audioItemId: Number(audioItemId)});
            }
            // 查询当前用户播放的对应的类别
            const item = await exesql('SELECT `audio_device`.`category_id` FROM `audio_device` WHERE `audio_device`.`uuid`= ? AND `audio_device`.`audio_id`= ?  LIMIT 1;', [uuid,Number(audioItemId)]);
            if (item.err) {
                sendLogToEmail(item.err);
                return;
            }
            // 没有收藏过
            if (item.result.length) {
                // 更新 audio_device_play
                const category_id = item.result[0].category_id;
                await exesql('DELETE FROM `audio_device_play` WHERE `uuid`= ? AND `category_id` = ? ', [uuid, category_id]);
                exesql('INSERT INTO `audio_device_play` (`uuid`, `category_id`, `audio_id`,`update_time`) VALUES(?, ?, ?,CURRENT_TIMESTAMP);',
                    [uuid, category_id, parseInt(audioItemId, 10)]).then(function (result) {
                        if (result.err) {
                            sendLogToEmail(result.err);
                        }
                    });
            }

        }
    }

    // 设备消息发送改变
    async deviceInfoChanged(req, res) {
        const device_id = req.query.device_id;
        const type = req.query.type;
        const value = req.query.value;
        res.apiSuccess();
        console.log(`deviceInfoChanged:${device_id}, type:${type}, value:${value}`);
        try {
            sendMessageToDevice(parseInt(type,10), device_id, { value: parseInt(value,10) });
        } catch (error) {
            sendLogToEmail(error);
        }
    }

    // 设备端获取token
    async getWxAccessTokenToDevice(req, res) {
        const device_id = req.query.device_id;
        let post = {
            errcode: 0,
            errmsg: 'ok',
            access_token: ''
        }
        try {
            const wechatId = getWechatIdBySn(device_id);
            const accessToken = await this.getWxToken(wechatId);
            if (accessToken === '') {
                sendLogToEmail(`getWxAccessTokenToDevice wechatId:${wechatId}, 获取不到token,${device_id}`);
            }
            Object.assign(post, { access_token: accessToken })
        } catch (err) {
            sendLogToEmail(err);
        } finally {
            console.log(post);
            res.end(JSON.stringify(post));
        }
    }

    // 播放类别
    async playCategory(req, res) {
        const uuid = req.query.uuid;
        const category_id = req.query.category;
        console.log(`playCategory --> uuid:${uuid}, category_id:${category_id}`);

        try {
            // 先查询有没有收藏
            const iResult = await exesql('SELECT `id` FROM `audio_device` WHERE `uuid` = ? AND `category_id` = ? LIMIT 1;', [uuid, category_id]);
            if (iResult.err) {
                sendLogToEmail(iResult.err);
                res.apiSuccess();
                return;
            }
            if (iResult.result.length === 0) {
                res.apiError(API_CODE_NOT_STORE_AUDIO, 'Not yet collected');
                return;
            }

            const sql = 'SELECT `audio_device_play`.`audio_id` FROM `audio_device_play` WHERE `audio_device_play`.`uuid` = ?  AND  `audio_device_play`.`category_id` = ? LIMIT 1;';
            // 获取设备上次一次播放的类别的音频id
            const { err, result } = await exesql(sql, [uuid, category_id]);
            if (err) {
                sendLogToEmail(err);
                res.apiSuccess();
                return;
            }
            const data = await exesql('SELECT `access_token` FROM `device_uuid_list` WHERE `uuid`= ? LIMIT 1;', [uuid]);
            if (data.err) {
                sendLogToEmail(err);
                res.apiSuccess();
                return;
            }
            if (data.result.length === 0) {
                sendLogToEmail(`playCategory：${uuid}, ${category_id},找不到对应百度AccessToken`);
                res.apiSuccess();
                return;
            }
            // latestAudioId:0,表示从头开始,1:表示从上一次播放位置开始
            const latestAudioId = (result.length > 0) ? result[0].audio_id : 0;
            const access_token = data.result[0].access_token;
            res.apiSuccess();

            console.log(`uuid;${uuid}, access_token;${access_token},category_id;${category_id}, latestAudioId;${latestAudioId}`)

            audioCustomPlay(uuid, access_token, category_id, latestAudioId);

        } catch (error) {
            sendLogToEmail(error);
            res.apiSuccess();
        }
    }

    // 设备收藏音频
    async deviceCollectAudio(req, res) {
        const uuid = req.query.uuid;
        const audio_id = req.query.audio_id;
        if (audio_id.indexOf('-') >= 0) {
            res.apiError(NOT_SUPPORT_COLLECT_AUDIO, 'Not support collect audio');
            return;
        }

        try {
            const audioId = parseInt(audio_id, 10);
            const { err, result } = await exesql('SELECT `album_id` FROM `audio` WHERE `audio_id` = ? LIMIT 1;', [audioId]);
            if (err) {
                sendLogToEmail(err);
                res.apiError(-1, 'collect failed');
                return;
            }
            if (result.length === 1) {
                const ret = await exesql('SELECT `id` FROM `audio_device` WHERE `uuid` = ? AND `category_id` = ? AND `audio_id` = ? LIMIT 1', [uuid, FAVORITE_CATEGORY_ID, audioId]);
                if (ret.err) {
                    sendLogToEmail(ret.err);
                    res.apiError(-1, 'collect failed');
                    return;
                }
                // 不存在
                if (ret.result.length === 0) {
                    insertTable({ uuid: uuid, category_id: FAVORITE_CATEGORY_ID, audio_id: audioId, is_like: 1 }, 'audio_device');
                }
                res.apiSuccess();
            } else {
                console.log(`数据库中没有发现当前音频`);
                res.apiError(NOT_SUPPORT_COLLECT_AUDIO, 'Not support collect audio');
            }

        } catch (error) {
            sendLogToEmail(error);
            res.apiError(-1, error.stack);
        }

    }



    // 设备上线通知
    async deviceOnlineNotification(req, res) {
        const chip_id = req.query.chip_id;
        const mac = req.query.mac;
        const uuid = req.query.uuid;
        const device_id = req.query.device_id;
        const version = req.query.version;
        const firm_type_id = req.query.firm_type_id || 1;
        const ip = this.getClientIp(req);

        console.log(`设备上线通知:chip_id:${chip_id}, uuid:${uuid},device_id:${device_id} `, );

        // 发送MQTT消息
        sendMessageToDevice(0, device_id, { version: version });

        let sql = 'select chip_id from device_first_online where uuid =?';
        try {
            const { err, result } = await exesql(sql, [uuid]);
            if (err) {
                res.apiError(API_CODE_SERVER_ERR, err.stack);
                sendLogToEmail(err);
                return;
            }
            if (result.length > 0) {
                console.log(`chip_id=${chip_id}, ${JSON.stringify(result)}`);
                if (result[0].chip_id && chip_id != result[0].chip_id) {
                    sql = 'call duplicate_uuid_handle(?, ?,?)'
                    const { err, result } = await exesql(sql, [uuid, chip_id, ip])
                    if (err) {
                        res.apiError(API_CODE_SERVER_ERR, err.stack);
                        sendLogToEmail(err);
                        return;
                    }
                    if (result.length > 0) {
                        let ret = result[0][0];
                        if (ret.errcode == 1000 || ret.errcode == 1001) {
                            res.end(JSON.stringify(result[0][0]));
                        } else {
                            res.apiError(1000, "the uuid has been used")
                            sendLogToEmail("空中发送ID错误，可能是ID不够" + JSON.stringify(result[0][0]))
                        }
                        return;
                    }
                }
            }

            this.handleOtaVersion(uuid, version, (ret) => {
                if (ret) {
                    // 有升级版本
                    const result = Object.assign(ret, { errcode: 1005, errmsg: 'ok' });
                    console.log('有升级版本:', result);
                    res.setHeader("Content-Type", "application/json");
                    res.end(JSON.stringify(result));
                } else {
                    res.apiSuccess();
                }
            });

            // 插入到 device_first_online
            sql = 'insert into device_first_online(sn, version, uuid, chip_id, mac,ip)values(?,?,?,?,?,?)';
            await exesql(sql, [device_id, version, uuid, chip_id, mac, ip]);

            // 插入到 device_online_log
            sql = 'insert into device_online_log(sn, version, uuid, chip_id, mac,ip)values(?,?,?,?,?,?)';
            exesql(sql, [device_id, version, uuid, chip_id, mac, ip]);

            // 更新 device
            sql = 'update device set chip_id=?, mac=?, version=?, last_access=CURRENT_TIMESTAMP, firm_type_id=?,ip=? where uuid =?';
            await exesql(sql, [chip_id, mac, version, firm_type_id, ip, uuid]);

            // 查询最后一次没有通知成功的音频
            const lastVoiceSql = 'SELECT media_id,notify_status FROM wx_voice WHERE device_sn=? ORDER BY void_id DESC LIMIT 1; ';
            const voiceResult = await exesql(lastVoiceSql, [device_id]);
            if (!voiceResult.err && voiceResult.result.length) {
                const voice = voiceResult.result[0];
                if (voice.notify_status === 0) {
                    const retCode = this.sendLatestVoiceToDevice(device_id, voice.media_id);
                    if (retCode === 0 || retCode === 1005) {
                        const sql = 'UPDATE `wx_voice` SET `notify_status` = 1 WHERE `device_sn` = ? AND `media_id` = ? ;';
                        await exesql(sql, [device_id, voice.media_id]);
                    }
                }
            }

        } catch (err) {
            console.log(`deviceOnlineNotification:`, err);
            sendLogToEmail(err);
        }
    }

    // 处理是OTA升级 
    async handleOtaVersion(uuid, old_version, cb) {

        // 是否需要升级
        const updateSql = 'SELECT `ota_upgrade_strategic`.`is_quiet`,`ota_version`.`version`,`ota_version`.`url` FROM `ota_upgrade_strategic`,`ota_version` ' +
            ' WHERE `ota_upgrade_strategic`.`status` = 1  AND `ota_upgrade_strategic`.`stractegic_id` = 0 AND `ota_upgrade_strategic`.`old_version` = ?  AND ' +
            ' `ota_upgrade_strategic`.`new_version` = `ota_version`.`version` ORDER BY `ota_upgrade_strategic`.`id` DESC LIMIT 1;';
        console.log(`updateSql:${updateSql}`);
        const data = await exesql(updateSql, [old_version]);
        if (data.err) {
            cb(null);
            console.log(data.err);
            sendLogToEmail(data.err);
            return;
        }

        if (data.result.length > 0) {
            const isQuiet = data.result[0].is_quiet;
            console.log(`isQuiet:${isQuiet}`);
            cb({ ota_type: isQuiet, ota_url: data.result[0].url, ota_version: data.result[0].version });
            return;
        }
        // 升级的URL查询
        console.log(`查询用户手动升级`);
        const urlSql = 'SELECT `ota_device_upgrade`.`new_version`,`ota_version`.`url` FROM `ota_device_upgrade`,`ota_version` ' +
            'WHERE  `ota_device_upgrade`.`uuid` = ? AND `ota_device_upgrade`.`status` = 0 AND `ota_device_upgrade`.`old_version` = ?  AND  `ota_device_upgrade`.`new_version` = `ota_version`.`version` ORDER BY `ota_version`.`version_id` DESC LIMIT 1;'
        console.log(`urlSql:${urlSql}`);
        const { err, result } = await exesql(urlSql, [uuid, old_version]);
        if (err) {
            cb(null);
            console.log(err);
            sendLogToEmail(err);
            return;
        }
        if (result.length === 0) {
            cb(null);
            console.log('没有找到升级的URL');
            return;
        }
        cb({ ota_type: 1, ota_url: result[0].url, ota_version: result[0].new_version });
    }


    /**
     * 百度设备上传的语音信息
     */
    async saveBaiduVoiceInfo(req, res) {
        // 存储百度语音信息
        const { uuid, voice_id, ask, reply } = req.body;
        console.log('saveBaiduVoiceInfo:', uuid);
        try {
            if (ask) {
                // 新增询问语音信息
                const insertSql = 'insert into baidu_voice(uuid,voice_id, ask, reply) values (?,?,?,?);';
                const { err, result } = await exesql(insertSql, [uuid, voice_id, JSON.stringify(ask), '']);
                if (err) {
                    sendLogToEmail(err);
                }
            } else {
                // 更新对应的语音信息
                const updateSql = "UPDATE baidu_voice as B SET B.reply = ?  WHERE B.uuid = ? AND B.id = (SELECT A.id FROM (SELECT id FROM baidu_voice as A WHERE A.uuid= ?  AND A.voice_id = ? ORDER BY A.id DESC LIMIT 1) AS A)";
                const { err, result } = await exesql(updateSql, [JSON.stringify(reply), uuid, uuid, voice_id])
                if (err) {
                    sendLogToEmail(err);
                }
            }
        } catch (err) {
            sendLogToEmail(err);
        } finally {
            res.end(JSON.stringify({ errcode: 0 }));
        }
    }

    // 百度服务器验证token
    async verifyBaiduToken(req, res) {
        const access_token = req.query.access_token;
        console.log(`百度服务器验证 token:${access_token}`);
        let post = { access_token: access_token };
        const sql = 'SELECT `uuid` FROM `device_uuid_list` WHERE `access_token` = ? LIMIT 1;';
        try {
            const { err, result } = await exesql(sql, [access_token]);
            if (err) {
                sendLogToEmail(err);
            } else {
                if (result.length > 0) {
                    // 过期时长一个月
                    Object.assign(post, {
                        uid: result[0].uuid,
                        access_token: access_token,
                        created_at: Math.floor(new Date().getTime()),
                        expires_in: 2678400,
                    });
                }
            }
        } catch (err) {
            sendLogToEmail(err);
        } finally {
            res.setHeader("Content-Type", "application/json");
            res.end(JSON.stringify(post));
        }
    }

    // 自定义播放类别
    async customPlayList(req, res) {
        const deviceUuid = req.query.deviceUuid;
        let category_id = req.query.category_id;
        let latestAudioId = req.query.audio_id;
        console.log(`deviceUuid:${deviceUuid}, category_id:${category_id}, 上一次播放音频记录;${latestAudioId}`);
        // 定义播放列表
        let playList = [];
        res.setHeader("Content-Type", "application/json");
        try {
            let sql = "";
            //  百度请求播放列表
            if (!category_id && !latestAudioId) {
                const { err, result } = await exesql('SELECT `category_id`,`audio_id` FROM `audio_device_play` WHERE `uuid` = ? ORDER BY `update_time` DESC LIMIT 1;', [deviceUuid]);
                if (err || result.length === 0) {
                    if (err) {
                        console.log(err);
                        sendLogToEmail(err);
                    }
                    res.json({
                        errcode: 0,
                        errmsg: 'ok',
                        result: {
                            list: playList
                        }
                    });
                    return;
                }
                category_id = result[0].category_id;
                latestAudioId = result[0].audio_id;
            }

            // 我的最爱
            const isFavorite = (category_id && parseInt(category_id, 10) === FAVORITE_CATEGORY_ID);
            if (isFavorite) {
                let id = 0;
                if (latestAudioId > 0) {
                    // 从指定位置播放
                    const findSql = 'SELECT `id` FROM `audio_device` WHERE `audio_device`.`audio_id` = ?  AND `audio_device`.`uuid` = ? AND `audio_device`.`is_like` = 1 LIMIT 1;';
                    const result = await exesql(findSql, [latestAudioId, deviceUuid]);
                    if (!result.err && result.result.length > 0) {
                        id = result.result[0].id;
                    }
                    sql = "SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ?  AND `audio_device`.`is_like` = 1 AND `audio_device`.`id` > " + id + " LIMIT ?;";
                } else {
                    // 从头开始播放
                    sql = "SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ?  AND `audio_device`.`is_like` = 1  LIMIT ?;";
                }
                const {err ,result } = await exesql(sql, [deviceUuid, PLAY_LIST_LIMIT_SIZE]);
                if (err) {
                    sendLogToEmail(`customPlayList -> categoryRet,deviceUuid:${deviceUuid},category_id:${category_id},latestAudioId:${latestAudioId},err;${err.stack}`);
                    res.json({
                        errcode: 0,
                        errmsg: 'ok',
                        result: {
                            list: playList
                        }
                    });
                    return;
                }
                playList = result.map((item) => {
                    return item.audio_id;
                })
                const missingNum = PLAY_LIST_LIMIT_SIZE - result.length;
                if (latestAudioId > 0 && missingNum > 0){
                    const {err, result } = await exesql("SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ?  AND `audio_device`.`is_like` = 1 AND `audio_device`.`id` <= ?  LIMIT ?;", [deviceUuid, id,Math.abs(missingNum)]);
                    if (err) {
                        sendLogToEmail(`customPlayList -> favoriteRet,deviceUuid:${deviceUuid},category_id:${category_id},latestAudioId:${latestAudioId},err;${err.stack}`);
                    } else {
                        const appendList = result.map((item) => {
                            return item.audio_id;
                        });
                        playList = playList.concat(appendList);
                    }
                }

            } else {
                // 点播其他类别
                let id = 0;
                if (latestAudioId > 0) {
                    // 从指定位置播放
                    const findSql = 'SELECT `id` FROM `audio_device` WHERE `audio_device`.`audio_id` = ? AND  `audio_device`.`uuid` = ? AND `audio_device`.`category_id` = ? LIMIT 1;';
                    const result = await exesql(findSql, [latestAudioId, deviceUuid, category_id]);
                    if (!result.err && result.result.length > 0) {
                        id = result.result[0].id;
                    }
                    sql = "SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ? AND `audio_device`.`category_id` = ? AND `audio_device`.`id` > " + id + " LIMIT ?;";
                } else {
                    // 从头开始播放
                    sql = "SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ? AND `audio_device`.`category_id` = ? LIMIT ?;";
                }
                const { err, result } = await exesql(sql, [deviceUuid, category_id, PLAY_LIST_LIMIT_SIZE]);
                if (err) {
                    sendLogToEmail(`customPlayList -> categoryRet,deviceUuid:${deviceUuid},category_id:${category_id},latestAudioId:${latestAudioId},err;${err.stack}`);
                    res.json({
                        errcode: 0,
                        errmsg: 'ok',
                        result: {
                            list: playList
                        }
                    });
                    return;
                }
                playList = result.map((item) => {
                    return item.audio_id;
                })

                const missingNum = PLAY_LIST_LIMIT_SIZE - result.length;
                if (latestAudioId > 0 && missingNum > 0) {
                    const { err, result } = await exesql("SELECT `audio_id` FROM `audio_device` WHERE `audio_device`.`uuid` = ? AND `audio_device`.`category_id` = ? AND `audio_device`.`id` <= ? LIMIT ?;", [deviceUuid, category_id, id,Math.abs(missingNum)]);
                    if (err) {
                        sendLogToEmail(`customPlayList -> categoryRet,deviceUuid:${deviceUuid},category_id:${category_id},latestAudioId:${latestAudioId},err:${err.stack}`);
                    } else {
                        const appendList = result.map((item) => {
                            return item.audio_id;
                        });
                        playList = playList.concat(appendList);
                    }
                }
            }
        } catch (error) {
            sendLogToEmail(`程序异常:customPlayList -> categoryRet,deviceUuid:${deviceUuid},category_id:${category_id},latestAudioId:${latestAudioId},error:${error.stack}`);
        } finally {
            console.log(`列表个数:${playList.length},`, playList);
            res.json({
                errcode: 0,
                errmsg: 'ok',
                result: {
                    list: playList
                }
            });
        }
    }



    // 重新加载配置
    async reloadPublicPlatform(req, res) {
        console.log(`[${cluster.worker.id}],通知[master]更新配置信息`);
        process.send(NOTIFY_MASTER_RELOAD_PLARFORM);
        res.apiSuccess();
    }

    getWxToken(wechat_id) {
        return new Promise(function (resolve, reject) {
            getWxAccessToken(wechat_id, function (token) {
                return resolve(token);
            })
        });
    }

    // 延迟
    sleep(millisecond) {
        return new Promise(function (reslove, reject) {
            setTimeout(reslove, millisecond);
        })
    }

    getClientIp(req) {
        let ipAddress = req.headers['x-forwarded-for'] ||
            req.connection.remoteAddress ||
            req.socket.remoteAddress ||
            req.connection.socket.remoteAddress;
        if (ipAddress.split(',').length > 0) {
            ipAddress = ipAddress.split(',')[0];
        }
        const arr = ipAddress.split(':');
        const ip = arr[arr.length - 1];
        return ip;
    };

    // 发送最后一条离线消息给设备
    async sendLatestVoiceToDevice(device_sn, media_id) {
        const sql = 'SELECT `uuid`,`token` FROM `device` WHERE sn = ? LIMIT 1;'
        try {
            const { err, result } = await exesql(sql, [device_sn]);
            if (err || result.length === 0) {
                return -1;
            }
            const data = await control(result[0].uuid, { type: 5, media_id: media_id }, result[0].token);
            if (data.err) {
                sendLogToEmail(data.err);
                return -1;
            }
            if (parseInt(data.result.code, 10) === 0) {
                const sql = 'UPDATE `wx_voice` SET `notify_status` = 1 WHERE `device_sn` = ? AND `media_id` = ? ;';
                await exesql(sql, [device_sn, media_id]);
            }
        } catch (err) {
            sendLogToEmail(err);
        }
        return 0;
    }


}

export default new ThirdApi();